package com.power.sifa.statistics.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.plf.common.domain.ResponseDTO;
import com.plf.common.exception.BusinessException;
import com.power.flowable.api.IPersonalFeign;
import com.power.flowable.model.pageinfo.BusinessPageInfo;
import com.power.sifa.approve.model.Apl_arrive_detail;
import com.power.sifa.approve.model.enumeration.St_admreview;
import com.power.sifa.approve.model.enumeration.St_apply;
import com.power.sifa.approve.service.Apl_arrive_detailService;
import com.power.sifa.approve.service.impl.Apl_mainServiceImpl;
import com.power.sifa.net.model.enumeration.Tp_matter;
import com.power.sifa.statistics.api.IApl_statisticFeign;
import com.power.sifa.statistics.model.pageInfo.StatisticsInfo;
import com.power.sifa.statistics.model.vo.HomeUndoEvent;
import com.power.sifa.statistics.service.Apl_statisticService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @ClassName Apl_statisticController
 * @Author xiongzw
 * @Date 2023/11/3 9:07
 * @Description 首页统计接口类
 * @Version: 1.0
 **/

@Slf4j
@RestController
@Api(value = "Apl_statisticController", tags = {"首页统计"})
public class Apl_statisticController implements IApl_statisticFeign {


    @Resource
    private IPersonalFeign iPersonalFeign;
    @Resource
    private Apl_statisticService apl_statisticService;
    @Resource
    private Apl_mainServiceImpl apl_mainServiceImpl;

    @Resource
    private Apl_arrive_detailService apl_arrive_detailService;

    /**
     * 送达的标识KEY
     */
    private final static Integer SEND_ENUM_KEY = 1000;
    /**
     * 复议监督的标识KEY
     */
    private final static Integer SUPERVISE_ENUM_KEY = 2000;
    /**
     * 线程池
     */
    public ExecutorService threadPool = new ThreadPoolExecutor(8, 16, 2, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

    /**
     * 首页统计-询登录人的待处理事件，按照流程环节分类
     *
     * @param userid
     * @return
     */
    @Override
    public ResponseDTO queryUndoEvents(String userid) throws BusinessException {
        Assert.notNull(userid, "userid不能为空");
        Map<Integer, List> homeUndoEvents = new HashMap<>();
        BusinessPageInfo pageInfo = new BusinessPageInfo();
        // 设置当前的查询状态
        pageInfo.setStatusapply(St_admreview.todoStatus);
        // 默认流程中的状态
        pageInfo.setState(1);
        // Tp_biztype.ACCEPT
        pageInfo.setBizenum(1000);
        pageInfo.setPageSize(9999);
        pageInfo.setPageNumber(1);
        pageInfo.setMatid(Tp_matter.PUB_ADMREVIEW);
        // 查询行政复议的当前的待处理的数据
        ResponseDTO res = this.iPersonalFeign.taskList(userid, pageInfo);
        // 查询复议监督的待处理的数据
        BusinessPageInfo supervisePageInfo = new BusinessPageInfo();
        // 设置当前的查询状态
        // 默认流程中的状态
        supervisePageInfo.setState(1);
        // Tp_biztype.SUPERVISE
        supervisePageInfo.setBizenum(3000);
        supervisePageInfo.setPageSize(9999);
        supervisePageInfo.setPageNumber(1);
        supervisePageInfo.setCategorynone("assignment");
        supervisePageInfo.setMatid(Tp_matter.PUB_SUPERVISE);
        // 查询复议监督当前的待处理数据
        ResponseDTO res2 = this.iPersonalFeign.taskList(userid, supervisePageInfo);
        // 查询未送达文件
        List<Apl_arrive_detail> arriveNoticeList = this.apl_arrive_detailService.getByUserid(userid);
        if (0 != res.getCode() || 0 != res2.getCode()) {
            log.error("查询当前行政复议待处理报错 -> msg[{}]", res.getMsg());
            log.error("查询当前复议监督待处理报错 -> msg[{}]", res2.getMsg());
            throw new BusinessException(res.getMsg());
        } else {
            // 查询当前的数据
            Map<String, Object> pageData = (Map<String, Object>) res.getData();
            if (ObjectUtil.isNotNull(pageData)) {
                List<Map<String, Object>> dataList = (List<Map<String, Object>>) pageData.get("records");
                if (CollUtil.isNotEmpty(dataList)) {
                    // 将对应的类型进行转换
                    List<HomeUndoEvent> undoEventList = dataList.stream().map(HomeUndoEvent::new).collect(Collectors.toList());
                    // 针对类型进行分类转换
                    undoEventList.forEach(event -> {
                        Integer status = event.getStatus();
                        // 待受理，待补正，待调解 统一为待受理状态
                        if (status.equals(St_admreview.UNDO) || status.equals(St_admreview.APPEND) || status.equals(St_admreview.TOMEDIATE)) {
                            List<HomeUndoEvent> list = homeUndoEvents.get(St_admreview.UNDO);
                            if (CollectionUtil.isEmpty(list)) {
                                list = new ArrayList<>();
                            }
                            list.add(event);
                            homeUndoEvents.put(St_admreview.UNDO, list);
                        } else if (status.equals(St_admreview.ACCEPT)) {
                            List<HomeUndoEvent> list = homeUndoEvents.get(status);
                            if (CollectionUtil.isEmpty(list)) {
                                list = new ArrayList<>();
                            }
                            list.add(event);
                            homeUndoEvents.put(St_admreview.ACCEPT, list);
                        }
                    });
                }
            }
            Map<String, Object> supervisePageData = (Map<String, Object>) res2.getData();
            if (ObjectUtil.isNotNull(supervisePageData)) {
                List<Map<String, Object>> superviseList = (List<Map<String, Object>>) supervisePageData.get("records");
                if (CollUtil.isNotEmpty(superviseList)) {
                    homeUndoEvents.put(SUPERVISE_ENUM_KEY, superviseList);
                }
            }
            if (CollectionUtil.isNotEmpty(arriveNoticeList)) {
                homeUndoEvents.put(SEND_ENUM_KEY, arriveNoticeList);
            }
        }
        return ResponseDTO.succData(homeUndoEvents);
    }

    /**
     * 首页统计-统计行政行为的柱状图
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countPrtypeList(@RequestBody StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countPrtypeList(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "统计行政行为异常");
        }
    }

    /**
     * 首页统计-统计决定类型
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countDecisionType(@RequestBody StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countDecisionType(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "统计决定类型异常");
        }
    }


    /**
     * 首页统计-统计被申请人
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countTargetTop(@RequestBody StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countTargetTop(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "统计被申请人异常");
        }
    }


    @Override
    public ResponseDTO queryCaseStatistics(String userid) throws BusinessException {
        // 异步线程数
        CountDownLatch latch = new CountDownLatch(3);

        BusinessPageInfo pageInfo = new BusinessPageInfo();
        // 设置当前的查询状态
        pageInfo.setStatusapply(St_admreview.todoStatus);
        // 默认流程中的状态
        pageInfo.setState(1);
        pageInfo.setBizenum(1000);
        pageInfo.setPageSize(9999);
        pageInfo.setPageNumber(1);
        pageInfo.setMatid(Tp_matter.PUB_ADMREVIEW);
        Map<String, Object> result = new HashMap<>(16);
        // 1. 我的待办总数
        {
            Runnable runner = () -> {
                Thread.currentThread().setName("thread-pool-taskList");
                // 查询当前的待处理的数据
                ResponseDTO res = this.iPersonalFeign.taskList(userid, pageInfo);
                Integer total = (Integer) ((Map) res.getData()).get("total");
                result.put("todoTotal", total);
                latch.countDown();
            };
            threadPool.execute(runner);
        }

        // 2. 我的已办总数
        {
            Runnable runner = () -> {
                Thread.currentThread().setName("thread-pool-endBusinessList");
                Integer total = this.apl_mainServiceImpl.countByUserAndStatus(userid, St_apply.COMPLETELIST);
                if (null != total) {
                    result.put("compleTotal", total);
                } else {
                    result.put("compleTotal", total);
                }
                latch.countDown();
            };
            threadPool.execute(runner);
        }

        // 3. 全局已办总数
        {
            Runnable runner = () -> {
                Thread.currentThread().setName("thread-pool-countByStatus");
                Integer total = this.apl_mainServiceImpl.countByStatus(St_apply.COMPLETELIST);
                if (null != total) {
                    result.put("allTotal", total);
                } else {
                    result.put("allTotal", total);
                }
                latch.countDown();
            };
            threadPool.execute(runner);
        }

        try {
            // 等待子线程结束
            latch.await();
            Thread.sleep(500);
        } catch (InterruptedException e) {
            log.error("/statistic/queryCaseStatistics 线程 latch await" + e.getMessage());
            Thread.currentThread().interrupt();
        }
        return ResponseDTO.succData(result);
    }

    /**
     * 大屏统计-统计案件状态
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countCaseStatus(@RequestBody StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countCaseStatus(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "统计案件状态异常");
        }
    }

    /**
     * 大屏统计--统计案件年度月度变化
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countCaseChangeYear(@RequestBody StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countCaseChangeYear(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "统计案件年度月度变化");
        }
    }


    /**
     * 大屏统计--行政应诉案件统计
     *
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO CountRespondCase() throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.CountRespondCase());
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政应诉案件统计异常");
        }
    }

    @Override
    public ResponseDTO caseStatus(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.caseStatus(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议案件情况统计异常");
        }
    }

    @Override
    public ResponseDTO countFinish(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countFinish(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议情况统计异常");
        }
    }

    @Override
    public ResponseDTO caseReceptionStatus(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.caseReceptionStatus(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议情况统计异常");
        }
    }

    @Override
    public ResponseDTO countCaseType(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countCaseType(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议案件类型统计异常");
        }
    }

    @Override
    public ResponseDTO countClosing(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countClosing(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议结案类型统计异常");
        }
    }


    /***
     * 结案类型统计
     *
     * @param info
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countClosingType(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countClosingType(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议结案类型统计异常");
        }
    }

    /**
     * 大屏统计--收案数据统计
     *
     * @param info
     * @return
     * @throws BusinessException
     */
    @Override
    public ResponseDTO countReceiptData(StatisticsInfo info) throws BusinessException {
        try {
            return ResponseDTO.succData(apl_statisticService.countReceiptData(info));
        } catch (BusinessException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseDTO.wrap(500, "行政复议收案数据统计异常");
        }
    }

}
